﻿#include<iostream>
#include<pthread.h>
#include<stdlib.h>
#include<stdio.h>
#include<sys/time.h>
#include<unistd.h>
using namespace std;

const int worker_count = 8;//num of thread
const int n = 1000;
float A[n][n];

struct threadParam_t {
    int k, t_id;
};

void* threadFunc(void* param) {
    threadParam_t* p = (threadParam_t*)param;
    int k = p->k;
    int t_id = p->t_id;
    for (int i = k + t_id + 1; i < n; i += worker_count) {
        for (int j = k + 1; j < n; j += 4) {
            if (j + 4 > n)
                while (j < n)
                    A[i][j++] = A[i][j] - A[i][k] * A[k][j];
            else {
                float32x4_t temp1 = vld1q_f32(A[i] + j);
                float32x4_t temp2 = vld1q_f32(A[k] + j);
                float32x4_t temp3 = vld1q_f32(A[i] + k);
                temp2 = vmulq_f32(temp3, temp2);
                temp1 = vsubq_f32(temp1, temp2);
                vst1q_f32(A[i] + j, temp1);
            }
        }
        A[i][k] = 0;
    }
    pthread_exit(NULL);
}
void dothread() {
    for (int k = 0; k < n; k++) {
        float32x4_t vt = vmovq_n_f32(A[k][k]);
        for (int j = k + 1; j < n; j += 4) {
            if (j + 4 > n)
                while (j < n)
                    A[k][j++] = A[k][j] / A[k][k];
            else {
                float32x4_t va = vld1q_f32(A[k] + j);
                va = vmulq_f32(va, vt);
                vst1q_f32(A[k] + j, va);
            }
        }
        A[k][k] = 1.0;

        pthread_t* handles = new pthread_t[worker_count];// 创建对应的 Handle
        threadParam_t* param = new threadParam_t[worker_count];

        for (int t_id = 0; t_id < worker_count; t_id++) {
            param[t_id].k = k;
            param[t_id].t_id = t_id;
        }
        for (int t_id = 0; t_id < worker_count; t_id++)
            pthread_create(&handles[t_id], NULL, threadFunc, (&param[t_id]));
        for (int t_id = 0; t_id < worker_count; t_id++)
            pthread_join(handles[t_id], NULL);
        delete[] handles;
        delete[] param;
    }
}
int main() {
    double time = 0.0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < i; j++)
            A[i][j] = 0;
        A[i][i] = 1.0;
        for (int j = i + 1; j < n; j++)
            A[i][j] = rand();
    }
    for (int k = 0; k < n; k++)
        for (int i = k + 1; i < n; i++)
            for (int j = 0; j < n; j++)
                A[i][j] += A[k][j];

    struct  timeval  tv_begin, tv_end;
    gettimeofday(&tv_begin, NULL);
    dothread();
        
    gettimeofday(&tv_end, NULL);
    time += (tv_end.tv_sec - tv_begin.tv_sec) * 1000000 + (tv_end.tv_usec - tv_begin.tv_usec);

    cout << time  << endl;
    return 0;
}

